﻿using Autofac;
using CSRedis;

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using SH.Common;
using SH.Common.DataDictionary;
using SH.Multitenant.Domain.Multitenant;
using SH.Multitenant.Domain.RBAC;
using SqlSugar;
using System.Reflection;
using System.Security.Claims;


namespace SH.Multitenant.Core.Saas
{

    public class DbManger
    {
        /// <summary>
        /// 获取业务库对象 （用IOC这块代码不能写到IOC里面）
        /// </summary>
        public static ISqlSugarClient BizDb
        {
            get
            {
                var tenantId = GetTenantId();//集团ID（也可以叫租户ID）
                Console.WriteLine(tenantId);
                //tenantId = _redis.Get<string>("tenantId");
                //根据Token获取用户信息和连接字符串信息
                //如果为null 切为默认库
                if (string.IsNullOrEmpty(tenantId))
                {
                    return MasterDb;
                }
                var options = Db.Queryable<DbOptions>().First(it => it.TenantId == tenantId);

                //判断当前上下文不存在则添加
                if (!Db.IsAnyConnection(tenantId))
                { //用非默认ConfigId进行测试
                  //添加业务库只在当前上下文有效（原理：SqlSugarScope模式入门文档去看）
                  //判断数据库是否存在
                    string conn = options.Conn;
                    Db.AsTenant().AddConnection(new ConnectionConfig()
                    {
                        ConfigId = tenantId,
                        ConnectionString = conn,
                        DbType = DbType.MySql,
                        IsAutoCloseConnection = true,
                        MoreSettings = new ConnMoreSettings
                        {
                            IsAutoDeleteQueryFilter = true,//启用删除查询过滤器  
                            IsAutoUpdateQueryFilter = true//启用更新查询过滤器 （表达式更新，如果是实体方式更新建议先查询在更新）
                        }
                    });
                    //把租户ID存redis中
                    var _redis = AppService.AutofacContainer.Resolve<CSRedisClient>();
                    _redis.Set("tenantId", tenantId);
                    _redis.Set("tenantConn", options.Conn);
                    #region 
                    //库不存在则建库
                    //Db.AsTenant().GetConnection(tenantId).DbMaintenance.CreateDatabase();
                    // 获取解决方案文件夹路径
                    //string solutionDirectory = Directory.GetParent(Directory.GetCurrentDirectory()).FullName;
                    // 获取所有 .cs 文件所在的文件夹
                    //string classesDirectory = Path.Combine(solutionDirectory, "SH.Multitenant.Domain", "RBAC");
                    //判断该目录是否存在
                    //if (Directory.Exists(classesDirectory))
                    //{
                    // 获取所有 .cs 文件
                    //var files = Directory.GetFiles(classesDirectory, "*.cs", SearchOption.AllDirectories);
                    //

                    //Type[] types = typeof(Employee).Assembly.GetTypes().Where(it => it.FullName.Contains("SH.Multitenant.Domain.RBAC")).ToArray();
                    //Db.GetConnection(tenantId).CodeFirst.InitTables(types);


                    //foreach (var type in types)
                    //{
                    // 加载 .cs 文件
                    //var assembly = Assembly.LoadFile(file);                        


                    //var classes = assembly.GetTypes().Where(t => t.IsClass);
                    //foreach (var cls in classes)
                    //{
                    //    //Console.WriteLine(cls.FullName);
                    //    //自动建表
                    //    Db.CodeFirst.InitTables(cls);
                    //}
                    //}
                    //}
                    #endregion
                }
                //原理说明
                //IsAnyConnection、AddConnection和GetConnection 都是Scope周期不同请求不会有影响
                var result = Db.GetConnection(tenantId);
                //接口过滤器 (继承接口的类都有效) 请升级 5.1.3.47
                Db.GetConnection(tenantId).QueryFilter.AddTableFilter<Tenant>(it => it.TenantId == tenantId);
                //全局设置删除
                //Db.Deleteable<Tenant>().EnableQueryFilter().Where(x => x.TenantId == user.TenantId).ExecuteCommand();

                return result;
            }
        }
        /// <summary>
        /// 获基础信息库对象 （用IOC这块代码不能写到IOC里面）
        /// </summary>
        public static ISqlSugarClient MasterDb
        {
            get
            {
                //如果是跨服务器分库，也需要动态配置的，因为库的IP会变
                //参考业务库用法
                //添加查询过滤器
                return Db.GetConnection("default");

            }
        }
        //通过IOC获取注入的Db对象
        public static SqlSugarScope Db
        {
            get
            {
                //如果用Furion就是 App.GetService<ISqlSugarClient>();
                //IOC不会可以看文档： https://www.donet5.com/Doc/27/2563
                var ihttp = AppService.Services.BuildServiceProvider().GetService<IHttpContextAccessor>();
                var obj = ihttp?.HttpContext?.RequestServices.GetService<ISqlSugarClient>();
                return (SqlSugarScope)obj;
            }
        }



        /// <summary>
        /// 获取用户数据库连接字符串信息 （从jwt或者ids4）
        /// </summary>
        /// <returns></returns>

        private static string GetTenantId()
        {
            var tenantId = "https://schemas.microsoft.com/identity/claims/tenantid";
            var claim = AppService.HttpContext?.User?.Claims?.SingleOrDefault(x => x.Type == tenantId);
            //var identity = _httpAccessor.HttpContext.User.Identity as ClaimsIdentity;
            //var claim = identity.FindFirst(x => x.Type == tenantId);
            //if (claim == null)
            //{
            //    throw new UnauthorizedAccessException("you have no permission!");
            //}
            //var tenant = u.TenantId = claim.Value;
            //if (tenant == null)
            //{
            //    throw new UnauthorizedAccessException($"{claim.Value} is unregistered ");
            //}
            return claim?.Value;
        }
    }
}



